#include "myc.h"

struct token *splitoken(char *sta,char *end) {
	struct token *fir,*cur;
	while (sta!=end && isspace(*sta)) sta++;
	if (sta==end) return NULL;
	fir=cur=calloc(1,sizeof(*cur));
	while (1) {
		cur->str=sta;
		if (is_letter(*sta)) {
			while (cur->str+cur->len!=end && is_alnum(cur->str[cur->len])) cur->len++;
			sta+=cur->len;
		}
		else if (isdigit(*sta)) {
			while (cur->str+cur->len!=end && isdigit(cur->str[cur->len])) cur->len++;
			sta+=cur->len;
			if (sta!=end && is_letter(*sta)) error("names must begin with letter or _");
		} else if (strchr("()[]{};,?:~.",*sta)) {
			sta+=cur->len=1;
		} else if (strchr("+&|",*sta)) {
			if (sta+1!=end && (sta[0]==sta[1] || sta[1]=='=')) sta+=cur->len=2;
			else sta+=cur->len=1;
		} else if (*sta=='-') {
			if (sta+1!=end && strchr("-=>",sta[1])) sta+=cur->len=2;
			else sta+=cur->len=1;
		} else if (strchr("*/%^|!=",*sta)) {
			if (sta+1!=end && sta[1]=='=') sta+=cur->len=2;
			else sta+=cur->len=1;
		} else if (strchr("<>",*sta)) {
			if (sta+1!=end && sta[1]=='=') sta+=cur->len=2;
			else if (sta+1!=end && sta[0]==sta[1])
				if (sta+2!=end && sta[2]=='=') sta+=cur->len=3;
				else sta+=cur->len=2;
			else sta+=cur->len=1;
		} else if (*sta=='\'') {
			if (sta+2>=end) error("unexpected EOF");
			if (sta[1]=='\\') {
				if (sta+3==end || sta[3]!='\'') error("missing '");
				sta+=cur->len=4;
			} else {
				if (sta[2]!='\'') error("missing '");
				sta+=cur->len=3;
			}
		} else if (*sta=='"') {
			while (++sta!=end && *sta!='"')
				if (*sta=='\\') sta++;
			if (sta==end) error("unexpected EOF");
			cur->len=++sta-cur->str;
		} else {
			char erm[]="invalid character '+'";
			erm[19]=*sta;
			error(erm);
		}
		while (sta!=end && isspace(*sta)) sta++;
		if (sta==end) return fir;
		cur->next=calloc(1,sizeof(*cur));
		cur->next->prev=cur;
		cur=cur->next;
	}
}

void freetokens(struct token* tok) {
	struct token *nex;
	while (tok) {
		nex=tok->next;
		free(tok);
		tok=nex;
	}
}